﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;

namespace MulticastTV
{
    /// <summary>
    /// Full screen EPG form with DataGridView and panel and background image
    /// </summary>
    public  partial class EPGWindowDaily : Form
    {
        Form1 parent;

        public delegate void delegateParent();
        public delegate void delegateParentInt(int chan);
        public delegate void delegateParentGetEpg(string chan, epgResult er);

        public static  DataTable dt = new DataTable();
        public static BindingSource bindingSource1 = new BindingSource();
        static DataColumn column1 = new DataColumn();
        static DataColumn column2 = new DataColumn();
        static DataColumn column3 = new DataColumn();

        bool allowupdate = true;

        /// <summary>
        /// Automatic item details update timer (when user changes selected item, this timer fires and starts updating function)
        /// </summary>
        public System.Windows.Forms.Timer TimerDetails = new System.Windows.Forms.Timer();
       
        /// <summary>
        /// Automatic daily epg update timer (when user changes current channel from epg, this timer fires and starts updating function)
        /// </summary>
        public System.Windows.Forms.Timer TimerChannelUpdate = new System.Windows.Forms.Timer();

        System.Windows.Forms.Timer TimerLabel10Blink = new System.Windows.Forms.Timer();
        System.Windows.Forms.Timer Timerautonextchan = new System.Windows.Forms.Timer();
        System.Windows.Forms.Timer Timerautoprevchan = new System.Windows.Forms.Timer();
        System.Windows.Forms.Timer Timerpreventtofast = new System.Windows.Forms.Timer();

        int upoffset = Properties.Settings.Default.EPGverticalOffset;
        int hofset = Properties.Settings.Default.EPGhorizontalOffset;

        /// <summary>
        /// Constructor
        /// </summary>
        public EPGWindowDaily(Form1 pr)
        {
            InitializeComponent();

            if (dt.Columns.Count < 3)
            {
                column1.DataType = System.Type.GetType("System.String");
                column1.ColumnName = "Name";
                column1.DefaultValue = "";
                column1.ReadOnly = false;
                column1.Unique = false;
                dt.Columns.Add(column1);

                column2.DataType = System.Type.GetType("System.String");
                column2.ColumnName = "Href";
                column2.DefaultValue = "";
                column2.ReadOnly = false;
                column2.Unique = false;
                dt.Columns.Add(column2);

                column3.DataType = typeof(DateTime);
                column3.ColumnName = "Date";
                column3.DefaultValue = DateTime.MinValue;
                column3.ReadOnly = false;
                column3.Unique = false;
                dt.Columns.Add(column3);
            }
            
            parent = pr;
            bindingSource1.DataSource = dt;
           
            dataGridView1.DataSource = bindingSource1;
            dataGridView1.Columns[1].Visible = false;
            dataGridView1.Columns[2].Visible = false;
            dataGridView1.AutoGenerateColumns = false;

            dataGridView1.MouseWheel +=new MouseEventHandler(dataGridView1_MouseWheel);

            TimerDetails.Interval = 300;
            TimerDetails.Tick+=new EventHandler(TimerDetails_Tick);

            TimerChannelUpdate.Interval = 300;
            TimerChannelUpdate.Tick+=new EventHandler(TimerChannelUpdate_Tick);

            TimerLabel10Blink.Interval = 200;
            TimerLabel10Blink.Tick+=new EventHandler(TimerRestoreLabel10Color_Tick);

            Timerautonextchan.Interval = 200;
            Timerautoprevchan.Interval = 200;
            Timerautonextchan.Tick+=new EventHandler(Timerautonextchan_Tick);
            Timerautoprevchan.Tick+=new EventHandler(Timerautoprevchan_Tick);

            //Timer that prevents to rapid update. it's needed because currently data is not cached.
            Timerpreventtofast.Interval = 600;
            Timerpreventtofast.Tick+=new EventHandler(Timerpreventtofast_Tick);
       }

        ~EPGWindowDaily()
        {
            deleteCache();
        }

        private void EPGWindowDaily_Load(object sender, EventArgs e)
        {
            //current datagrid font
            dataGridView1.RowsDefaultCellStyle.Font = ChangeFontSize(dataGridView1.RowsDefaultCellStyle.Font, Properties.Settings.Default.EPGDetailsTableFontSize);

            // row height
            dataGridView1.RowTemplate.Height = Properties.Settings.Default.EPGDetailsTableRowSize;

            calculateApproHeights();
            calculateApproWidhs();
            
            label1.Font = ChangeFontSize(label1.Font, Properties.Settings.Default.EPGDetailsFontSize + 4);
            label3.Font = ChangeFontSize(label3.Font, Properties.Settings.Default.EPGDetailsFontSize);
            label2.Font = ChangeFontSize(label2.Font, Properties.Settings.Default.EPGDetailsFontSize);
            label4.Font = ChangeFontSize(label4.Font, Properties.Settings.Default.EPGDetailsFontSize);
            label5.Font = ChangeFontSize(label5.Font, Properties.Settings.Default.EPGDetailsFontSize);
            label6.Font = ChangeFontSize(label6.Font, Properties.Settings.Default.EPGDetailsFontSize);
            label7.Font = ChangeFontSize(label7.Font, Properties.Settings.Default.EPGDetailsFontSize);
            label8.Font = ChangeFontSize(label8.Font, Properties.Settings.Default.EPGDetailsFontSize);
            label10.Font = ChangeFontSize(label10.Font, Properties.Settings.Default.EPGDetailsFontSize);
           
            label10.MouseWheel+=new MouseEventHandler(label10_MouseWheel);

            dataGridView1.FirstDisplayedCell = dataGridView1.CurrentCell;
            dataGridView1.Focus();

            if (Properties.Settings.Default.EPGBackground == false)
                clearBackground();
        }

        private void EPGWindowDaily_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                calculateApproHeights();
                calculateApproWidhs();
                
                // update label10 with current name
                updateWithCurrentSelectedChannel();

                // get data for current channel
                getDataForChannel();
            }
        }

        /// <summary>
        /// Update selected item datails
        /// </summary>
        public void getCurrentShowDetails()
        {
            try
            {
                EpgDetails sd = new EpgDetails(new epgDeatailsResult(),this);
                clearGui();
                if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Cells[1].Value.ToString() != "0")
                {
                    string href = dataGridView1.CurrentRow.Cells[1].Value.ToString();
                    sd.start(href);
                }
            }
            catch { }
        }

        /// <summary>
        /// Update GUI with parsed data
        /// </summary>
        /// <param name="res">Epg Details result</param>
        public void updateDetails(epgDeatailsResult res)
        {
            string[] input = res.EpgData;
            //string title, string genre, string description, string channelName, string time, string custom1Desc, string custom1, string custom2Desc, string custom2, picture
            if (input.Length > 0)
            {
                //update 
                updateTitle(input[0]);
                updateGenre(input[1]);
                updateDesc(input[2]);
                updateChanTime(input[3] + " " + input[4]);
                updateActors(input[5]);
                updateActorTitle(input[6]);
                updateDirector(input[7]);
                updateDirectorTitle(input[8]);
                if (input[9] != "")
                    updateImage(input[9]);
                else
                    clearImage();
            }
        }

        /// <summary>
        /// Select current item in epg table
        /// </summary>
        private void selectCurrent(int i)
        {
            try
            {
                if (dataGridView1.Rows.Count > 0 && dataGridView1.Rows.Count - 1 >= i)
                {
                    dataGridView1.CurrentCell = dataGridView1.Rows[Math.Max(i - 1, 0)].Cells[0];
                    dataGridView1.FirstDisplayedCell = dataGridView1.CurrentCell;
                    dataGridView1.Refresh();
                    if (this.Visible)
                        getCurrentShowDetails();
                }
            }
            catch { }
        }

        private void updateWithCurrentSelectedChannel()
        {
            label10.Text = parent.curcd.Num+" "+parent.curcd.Name;
            label10.Tag = new Label10Tag(parent.curcd.Name, parent.curcd.Num, parent.curcd.Ip);
        }

        //Note: This won't work if two channels have same number.
        public void setNextChannel(bool next, bool first, bool reset)
        {
            if (reset)
            {
                if (parent.dvchanepg.RowFilter != "")
                    parent.dvchanepg.RowFilter = "";
            }
            int count = parent.dvchanepg.Count;
            if (count == 0)
                return;
            int ci;
            if (!first)
                ci = parent.dvchanepg.Find(((Label10Tag)label10.Tag).Num);
            else
                ci = 0;

            int a, i;
            if (next)
                a = 1;
            else
                a = -1;

            if (ci != -1)
            {
                if (first)
                    i = 0;
                else if (ci + a >= count)
                    i = 0;
                else if (ci + a <= -1)
                    i = count - 1;
                else
                    i = ci + a;
                string lname = (string)parent.dvchanepg[i][2];
                int lnum = (int)parent.dvchanepg[i][1];
                string lip = (string)parent.dvchanepg[i][0];
                label10.Text = lnum.ToString() + " " + lname;
                label10.Tag = new Label10Tag(lname, lnum, lip);

                // Update data 
                TimerChannelUpdate.Stop();
                TimerChannelUpdate.Start();
            }
        }

        private void updateByFirstLetter(string letter)
        {
            string filter = "Name LIKE '" + letter + "*'";
            parent.dvchanepg.RowFilter = filter;
            if (((Label10Tag)label10.Tag).Name.ToUpper().StartsWith(letter.ToUpper()))
                setNextChannel(true, false, false);
            else
                setNextChannel(true, true, false);
        }

        private void getDataForChannel()
        {
            clearGui();
            dt.Clear();

            if (parent.epg == null)
                return;

            Label10Tag lt = (Label10Tag)label10.Tag;
            string name = lt.Name;
            string ip = lt.Ip;
            epgResult er = new epgResult(ip, name, "epg_form");
            if (parent.InvokeRequired)
                parent.Invoke(new delegateParentGetEpg(parent.epg.start), name, er);
            else
                parent.epg.start(name,er);
        }

        /// <summary>
        /// Populate datatable with epg items
        /// </summary>
        /// <param name="er">Epg result class with formated list</param>
        public void populateDatatable(epgResult er)
        {
            //clear again
            if (dt.Rows.Count > 0)
                dt.Clear();

            ensureVisible();

            DateTime curtime = DateTime.Now;
            DateTime refDate = DateTime.MinValue;
            bool pm = false;

            int count = er.EpgData.Count;
            if (count > 0)
            {
                if (!er.DatetimeFormat)
                {
                    string[] ard = (string[])(er.EpgData[count - 1]);
                    string rd = ard[0];
                    refDate = DateTime.ParseExact(rd, "yyyy-MM-dd HH:mm", null);
                }

                int i = 0;
                int current = 0;
                bool selected = false;
                dt.BeginLoadData();
                foreach (string[] sarr in er.EpgData)
                {
                    if (i == count - 1)
                        break;

                    DateTime itemtime;
                    if (!er.DatetimeFormat)
                    {
                        itemtime = new DateTime(refDate.Year, refDate.Month, refDate.Day, int.Parse(sarr[0].Substring(0, 2)), int.Parse(sarr[0].Substring(3, 2)), 0);
                        if (itemtime.Hour > 12)
                            pm = true;
                        if (pm && itemtime.Hour < 12)
                            itemtime = itemtime.AddDays(1);
                    }
                    else
                        itemtime = DateTime.ParseExact(sarr[0], "HH:mm yyyy-MM-dd", null);

                    int diff = itemtime.CompareTo(curtime);
                    if (diff >= 0 && !selected)
                    {
                        current = i;
                        selected = true;
                    }

                    // Add item to daily datatable
                    DataRow temp = dt.NewRow();
                    temp[0] = sarr[0].Split()[0] + "  " + sarr[1];
                    temp[1] = sarr[3];
                    temp[2] = itemtime;
                    dt.Rows.Add(temp);
                    i++;
                }
                dt.EndLoadData();
                selectCurrent(current);
            }
        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                getCurrentShowDetails();
            }
        }

        private void dataGridView1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (dataGridView1.RowCount > 0)
            {
                if (e.Delta > 16)
                    dataGridView1.FirstDisplayedScrollingRowIndex = Math.Max(dataGridView1.FirstDisplayedScrollingRowIndex - 1, 0);
                else if (e.Delta < -16)
                    dataGridView1.FirstDisplayedScrollingRowIndex = Math.Min(dataGridView1.FirstDisplayedScrollingRowIndex + 1, dataGridView1.Rows.Count);
            }
        }
 
        private void dataGridView1_MouseEnter(object sender, EventArgs e)
        {
            dataGridView1.Focus();
        }

       private void TimerDetails_Tick(object sender, EventArgs e)
       {
           getCurrentShowDetails();
           TimerDetails.Stop();
       }

       private void TimerChannelUpdate_Tick(object sender, EventArgs e)
       {
           if (allowupdate)
           {
               getDataForChannel();
               TimerChannelUpdate.Stop();
           }
           else
           { 
            //restart timer
               TimerChannelUpdate.Stop();
               TimerChannelUpdate.Start();
           }
       }

        private void TimerRestoreLabel10Color_Tick(object sender, EventArgs e)
        {
            label10.ForeColor = Color.White;
            TimerLabel10Blink.Stop();
        }

        private void Timerautonextchan_Tick(object sender, EventArgs e)
        {
            setNextChannel(true, false, true);
        }

        private void Timerautoprevchan_Tick(object sender, EventArgs e)
        {
            setNextChannel(false, false, true);
        }

        private void Timerpreventtofast_Tick(object sender, EventArgs e)
        {
            allowupdate = true;
        }

       private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
       {
           if (e.KeyCode == Keys.PageDown || e.KeyCode == Keys.PageUp || e.KeyCode == Keys.Enter)
               e.Handled=true;

           keyHandler(e.KeyCode);
       }

       private void EPGWindowDaily_KeyDown(object sender, KeyEventArgs e)
       {
           keyHandler(e.KeyCode);
       }

       private void keyHandler(Keys k)
       {
           if (k == Keys.Down || k == Keys.Up)
           {
               TimerDetails.Stop();
               TimerDetails.Start();
           }
           else if (k == Keys.PageDown)
           {
               panel1.AutoScrollPosition = new Point(0, Math.Min(panel1.VerticalScroll.Value + 10, panel1.VerticalScroll.Maximum));
           }
           else if (k == Keys.PageUp)
           {
               panel1.AutoScrollPosition = new Point(0, Math.Max(0, panel1.VerticalScroll.Value - 10));
           }
           else if (k == Keys.Left)
           {
               setNextChannel(false, false, true);
           }

           else if (k == Keys.Right)
           {
               setNextChannel(true, false, true);
           }
           else if (k == Keys.Escape || k == Keys.Delete)
               this.Visible = false;

           else if (k == Keys.Add)
               zoomIn();
           else if (k == Keys.Subtract)
               zoomOut();
           else if (k == Keys.D0)
               updateByFirstLetter("0");
           else if (k == Keys.D1)
               updateByFirstLetter("1");
           else if (k == Keys.D2)
               updateByFirstLetter("2");
           else if (k == Keys.D3)
               updateByFirstLetter("3");
           else if (k == Keys.D4)
               updateByFirstLetter("4");
           else if (k == Keys.D5)
               updateByFirstLetter("5");
           else if (k == Keys.D6)
               updateByFirstLetter("6");
           else if (k == Keys.D7)
               updateByFirstLetter("7");
           else if (k == Keys.D8)
               updateByFirstLetter("8");
           else if (k == Keys.D9)
               updateByFirstLetter("9");

           else if (k == Keys.Space)
           {
               // update label10 with current name
               updateWithCurrentSelectedChannel();
               // get data for current channel
               getDataForChannel();
           }

           else if (k == Keys.Back)
               toggleTransparent();
           else if (k == Keys.Enter)
               changeChannel();
       }

        /// <summary>
        /// Scroll details panel up
        /// </summary>
        public void scroll_UP()
        {
            panel1.AutoScrollPosition = new Point(0, Math.Max(0, panel1.VerticalScroll.Value - 10));
        }

        /// <summary>
        /// Scroll details panel down
        /// </summary>
        public void scroll_DOWN()
        {
            panel1.AutoScrollPosition = new Point(0, Math.Min(panel1.VerticalScroll.Value + 10, panel1.VerticalScroll.Maximum));
        }

        /// <summary>
        /// Select next item in table
        /// </summary>
        public void table_DOWN()
        {
            if (dataGridView1.Rows.Count > 0)
            {
                if (dataGridView1.CurrentRow.Index < dataGridView1.Rows.Count-1)
                {
                    dataGridView1.CurrentCell.Selected = false; 
                    dataGridView1.Rows[dataGridView1.CurrentRow.Index + 1].Selected = true;
                    dataGridView1.CurrentCell = dataGridView1.SelectedCells[0]; 
                    TimerDetails.Stop();
                    TimerDetails.Start();
                }
            }
        }

        /// <summary>
        /// Select previous item in table
        /// </summary>
        public void table_UP()
        {
            if (dataGridView1.Rows.Count > 0)
            {
                if (dataGridView1.CurrentRow.Index >= 1)
                {
                    dataGridView1.CurrentCell.Selected = false; 
                    dataGridView1.Rows[dataGridView1.CurrentRow.Index - 1].Selected = true;
                    dataGridView1.CurrentCell = dataGridView1.SelectedCells[0];
                    TimerDetails.Stop();
                    TimerDetails.Start();
                }
            }
        }

       /// <summary>
       /// Clear item details panel
       /// </summary>
       public void clearGui()
       {
           label1.Text = "";
           label3.Text = "";
           label2.Text = "";
           label4.Text = "";
           label5.Text = "";
           label7.Text = "";
           label8.Text = "";
           label6.Text = "";
           clearImage();
       }

       private void clearImage()
       {
           pictureBox1.Image = null;
       }

       private void updateTitle(string input)
       {
           label1.Text = input;
       }
       private void updateGenre(string input)
       {
           label3.Text = input;
       }

       private void updateDesc(string input)
       {
          label2.Text = input;
       }

       private void updateImage(string input)
       {
           pictureBox1.ImageLocation = input;
       }

       private void updateChanTime(string input)
       {
           label4.Text = input;
       }

       private void updateActors(string input)
       {
           label5.Text = input;
       }

       private void updateDirectorTitle(string input)
       {
           label6.Text = input;
       }

       private void updateDirector(string input)
       {
           label8.Text = input;
       }

       private void updateActorTitle(string input)
       {
           label7.Text = input;
       }

        private void calculateApproHeights()
       {
            //delta bottom
           int delta = Properties.Settings.Default.EPGPopUpHeight + Properties.Settings.Default.EPGpopupYOffset +10;
           
            //minimum shold be 60
           upoffset = Math.Max(Properties.Settings.Default.EPGverticalOffset,(int)Math.Round(0.145f * this.Height));
            
           int rowheight = dataGridView1.RowTemplate.Height;
           int proposedheight = this.Size.Height - upoffset - delta;
           int diffheight = proposedheight; 
           
           int i=0;
           for (i = 0; i < rowheight+1; i++)
           {
               if (diffheight % rowheight == 0)
               {
                   break;
               }
               diffheight--;
           }
           dataGridView1.Height = proposedheight - i + 3 ;
           panel1.Height = dataGridView1.Height;
       }

        private void calculateApproWidhs()
       {
           int offset = hofset;
           int width = Math.Max(this.Width - ((offset*2)+20),1);

           float rightF = (float)Properties.Settings.Default.EPGDetailsWidth/100;
           float leftF = 1.0f - rightF;
           
           float leftwidth = leftF * width;
           float rightwidth = rightF * width;

           int lw = Math.Max(1,(int)Math.Round(leftwidth));
           int rw = Math.Max(1,(int)Math.Round(rightwidth));
 
           dataGridView1.Location = new Point(offset, upoffset);
           dataGridView1.Width = lw;
           
           panel1.Location = new Point(offset+20 + dataGridView1.Width , upoffset);
           panel2.Location = new Point(offset+20 + dataGridView1.Width , upoffset-10);

           leftrightArrowLocation();
           alignLabels();

           panel1.Width = rw;
           panel2.Width = rw;
       }

       public void alignLabels()
       { 
           //label4 metrics
           int offset = hofset;
           int offsetbetweenline = 10;

           float label4ascentpx;
           float label4descentpx;
           label4ascentpx = label4.Font.Size * label4.Font.FontFamily.GetCellAscent(label4.Font.Style) / label4.Font.FontFamily.GetEmHeight(label4.Font.Style);
           label4descentpx = label4.Font.Size * label4.Font.FontFamily.GetCellDescent(label4.Font.Style) / label4.Font.FontFamily.GetEmHeight(label4.Font.Style);
           int label4height = (int)(Math.Round((label4descentpx * 2) + label4ascentpx))+6;
           
           label4.Location = new Point(offset+20 + dataGridView1.Width , Math.Max(1,panel2.Location.Y - offsetbetweenline-label4height));
           label4.Size = new Size(panel1.Size.Width, label4height);
           
           //label10 metrics
           float label10ascentpx;
           float label10descentpx;
           label10ascentpx = label10.Font.Size * label10.Font.FontFamily.GetCellAscent(label10.Font.Style) / label10.Font.FontFamily.GetEmHeight(label10.Font.Style);
           label10descentpx = label10.Font.Size * label10.Font.FontFamily.GetCellDescent(label10.Font.Style) / label10.Font.FontFamily.GetEmHeight(label10.Font.Style);
           int label10height = (int)(Math.Round((label10descentpx * 2) + label10ascentpx))+6;
           
           label10.Location = new Point(offset+pictureBox2.Width , Math.Max(1,dataGridView1.Location.Y-offsetbetweenline-4-label10height));
           label10.Size = new Size(Math.Max(1,dataGridView1.Width - (pictureBox2.Width * 2)), label10height);
       }

       public void leftrightArrowLocation()
       {
           int offset = hofset;
           pictureBox2.Location = new Point(offset, upoffset - pictureBox2.Height-1);
           pictureBox3.Location = new Point(offset + dataGridView1.Width - pictureBox3.Width,upoffset-pictureBox3.Height-1);
       }

       static public Font ChangeFontSize(Font font, float fontSize)
       {
           if (font != null)
           {
               float currentSize = font.Size;
               if (currentSize != fontSize)
               {
                   font = new Font(font.Name, fontSize,
                       font.Style, font.Unit,
                       font.GdiCharSet, font.GdiVerticalFont);
               }
           }
           return font;
       }

       private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
       {
           //do nothing
       }

       private void hideToolStripMenuItem_Click(object sender, EventArgs e)
       {
           this.Visible = false;
       }
 
       public void toggleTransparent()
       {
           if (this.BackColor == Color.Blue)
           {
               this.BackColor = Color.FromArgb(0, 0, 1);
               this.TransparencyKey  = this.BackColor;
               this.BackgroundImage = null;
               Properties.Settings.Default.EPGBackground = false;
               label9.Visible = false;
               pictureBox4.Visible = false;
           }
           else
           {
               this.BackColor = Color.Blue;
               this.TransparencyKey = Color.Empty;
               this.BackgroundImage = Properties.Resources.back3;
               Properties.Settings.Default.EPGBackground = true;
               label9.Visible = true;
               pictureBox4.Visible = true;
           }
       }

       private void clearBackground()
       {
           this.BackColor = Color.FromArgb(0, 0, 1); 
           this.TransparencyKey = this.BackColor;
           this.BackgroundImage = null;
           Properties.Settings.Default.EPGBackground = false;
           label9.Visible = false;
           pictureBox4.Visible = false;
       }

       private void toggleBackgroundToolStripMenuItem_Click(object sender, EventArgs e)
       {
           toggleTransparent();
       }

       public void zoomIn()
       {
           dataGridView1.RowsDefaultCellStyle.Font = ChangeFontSize(dataGridView1.RowsDefaultCellStyle.Font, dataGridView1.RowsDefaultCellStyle.Font.Size + 4);
           label1.Font = ChangeFontSize(label1.Font, label1.Font.Size+4 );
           label3.Font = ChangeFontSize(label3.Font, label3.Font.Size + 4);
           label2.Font = ChangeFontSize(label2.Font, label2.Font.Size + 4);
           label4.Font = ChangeFontSize(label4.Font, label4.Font.Size + 4);
           label5.Font = ChangeFontSize(label5.Font, label5.Font.Size + 4);
           label6.Font = ChangeFontSize(label6.Font, label6.Font.Size + 4);
           label7.Font = ChangeFontSize(label7.Font, label7.Font.Size + 4);
           label8.Font = ChangeFontSize(label8.Font, label8.Font.Size + 4);
           label10.Font = ChangeFontSize(label10.Font, label10.Font.Size + 4);
           alignLabels();
       }

        public void zoomOut()
        {
            dataGridView1.RowsDefaultCellStyle.Font = ChangeFontSize(dataGridView1.RowsDefaultCellStyle.Font, Math.Max(8,dataGridView1.RowsDefaultCellStyle.Font.Size - 4));
            label1.Font = ChangeFontSize(label1.Font, Math.Max (8,label1.Font.Size - 4));
            label3.Font = ChangeFontSize(label3.Font, Math.Max (8,label3.Font.Size - 4));
            label2.Font = ChangeFontSize(label2.Font, Math.Max (8,label2.Font.Size - 4));
            label4.Font = ChangeFontSize(label4.Font, Math.Max (8,label4.Font.Size - 4));
            label5.Font = ChangeFontSize(label5.Font, Math.Max (8,label5.Font.Size - 4));
            label6.Font = ChangeFontSize(label6.Font, Math.Max (8,label6.Font.Size - 4));
            label7.Font = ChangeFontSize(label7.Font, Math.Max (8,label7.Font.Size - 4));
            label8.Font = ChangeFontSize(label8.Font, Math.Max (8,label8.Font.Size - 4));
            label10.Font = ChangeFontSize(label10.Font, Math.Max (8,label10.Font.Size - 4));
            alignLabels();
        }

        private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                pictureBox2.Image = Properties.Resources.Back;
                // start auto update
                Timerautoprevchan.Stop();
                Timerautoprevchan.Start();
                setNextChannel(false, false, true);
            }
        }

        private void pictureBox2_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                pictureBox2.Image = Properties.Resources.Back_blue;
                // stop autoupdate
                Timerautonextchan.Stop();
                Timerautoprevchan.Stop();

                // restart tofast timer
                Timerpreventtofast.Stop();
                Timerpreventtofast.Start();
                if (allowupdate)
                {
                    TimerChannelUpdate.Stop();
                    getDataForChannel();
                    allowupdate = false;
                }
            }
        }

        private void pictureBox3_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                pictureBox3.Image = Properties.Resources.Next;
                //start autoupdate
                Timerautonextchan.Stop();
                Timerautonextchan.Start();
                setNextChannel(true, false, true);
            }
        }

        private void pictureBox3_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                pictureBox3.Image = Properties.Resources.Next_blue;
                //stop autoupdate
                Timerautonextchan.Stop();
                Timerautoprevchan.Stop();

                // restart tofast timer
                Timerpreventtofast.Stop();
                Timerpreventtofast.Start();
                if (allowupdate)
                {
                    TimerChannelUpdate.Stop();
                    getDataForChannel();
                    allowupdate = false;
                }
            }
        }

        private void label10_MouseEnter(object sender, EventArgs e)
        {
            label10.Focus();
        }

        private void label10_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 16)
                setNextChannel(true, false, true);
            else if (e.Delta < 16)
                setNextChannel(false, false, true);
        }

        private void label10_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            keyHandler(e.KeyCode);
            dataGridView1.Focus();
        }

        private void dataGridView1_KeyPress(object sender, KeyPressEventArgs e)
        {
            keypressedHandle(e);
        }

        private void keypressedHandle(KeyPressEventArgs e)
        {
            if (Char.IsLetter(e.KeyChar))
            {
                updateByFirstLetter(e.KeyChar.ToString());
                e.Handled = true;
            }
        }

        public void changeChannel()
        {
            TimerChannelUpdate.Stop();
            highlightChannelNameForASecond();
            if (parent.InvokeRequired)
                parent.Invoke(new delegateParentInt(parent.chantoip),((Label10Tag)label10.Tag).Num);
            else
                 parent.chantoip(((Label10Tag)label10.Tag).Num);
        }

        private void label10_Click(object sender, EventArgs e)
        {
             changeChannel();
        }

        private void highlightChannelNameForASecond()
        {
            label10.ForeColor = Color.FromArgb(198, 231, 124);
            TimerLabel10Blink.Start();
        }

        public void HidePanels()
        {
            if (this.BackColor == Color.FromArgb(0, 0, 1))
            {
                dataGridView1.Visible = false;
                panel1.Visible = false;
                panel2.Visible = false;
            }
        }

        public void ensureVisible()
        {
            if (!dataGridView1.Visible)
                dataGridView1.Visible = true;
            if (!panel1.Visible)
                panel1.Visible = true;
            if (!panel2.Visible)
                panel2.Visible = true;
        }

        private void pictureBox4_Click(object sender, EventArgs e)
        {
            this.Visible = false;
        }

        private void EPGWindowDaily_MouseMove(object sender, MouseEventArgs e)
        {
            if (!parent.mouseshown && (Math.Abs(parent.HiddemMousePos.X - Cursor.Position.X) > 2 || Math.Abs(parent.HiddemMousePos.Y - Cursor.Position.Y) > 2))
            {
                Cursor.Show();
                parent.mouseshown = true;
                parent.TimerMouseHide.Stop();
                parent.TimerMouseHide.Start();
            }
        }

        private void deleteCache()
        {
            if (Directory.Exists(EpgDetails.CachePath))
                Directory.Delete(EpgDetails.CachePath,true);
        }

        public void Clean()
        {
            bindingSource1.Dispose();
            column1.Dispose();
            column2.Dispose();
            Timerautonextchan.Dispose();
            Timerautoprevchan.Dispose();
            TimerChannelUpdate.Dispose();
            TimerDetails.Dispose();
            Timerpreventtofast.Dispose();
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        protected override void WndProc(ref Message m)
        {
            //remote controll
            if (m.Msg == 0x8888 && Properties.Settings.Default.RemoteMode2)
            {
                //repost to parent
                PostMessage(parent.Handle, m.Msg, (int)m.WParam, (int)m.LParam);
                m.Result = new IntPtr(0);
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        private void addToShedulerToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }

    public class Label10Tag
    {
        private string name;
        private int num;
        private string ip;

        public Label10Tag(string _name, int _num, string _ip)
        {
            name = _name;
            num = _num;
            ip = _ip;
        }
        
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public int Num
        {
            get { return num; }
            set { num = value; }
        }

        public string Ip
        {
            get { return ip; }
            set { ip = value; }
        }
    }
}
